1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
use crate::co;
use crate::decl::*;
use crate::msg::*;
use crate::prelude::*;

/// [`WM_NOTIFY`](https://learn.microsoft.com/en-us/windows/win32/controls/wm-notify)
/// message parameters.
///
/// Return type: `isize`.
pub struct Notify<'a> {
	pub nmhdr: &'a mut NMHDR,
}

unsafe impl<'a> MsgSend for Notify<'a> {
	type RetType = isize;

	fn convert_ret(&self, v: isize) -> Self::RetType {
		v
	}

	fn as_generic_wm(&mut self) -> WndMsg {
		WndMsg {
			msg_id: co::WM::NOTIFY,
			wparam: self.nmhdr.hwndFrom.ptr() as _,
			lparam: self.nmhdr as *mut _ as _,
		}
	}
}

unsafe impl<'a> MsgSendRecv for Notify<'a> {
	fn from_generic_wm(p: WndMsg) -> Self {
		Self {
			nmhdr: unsafe { &mut *(p.lparam as *mut _) },
		}
	}
}

impl<'a> Notify<'a> {
	/// Casts the `NMHDR` reference into a derived struct.
	///
	/// # Safety
	///
	/// The casting must be done to the correct struct.
	///
	/// You should always prefer the specific notifications, which perform this
	/// conversion for you.
	pub const unsafe fn cast_nmhdr<T>(&self) -> &T {
		&*(self.nmhdr as *const _ as *const _)
	}

	/// Casts the `NMHDR` mutable reference into a derived struct.
	///
	/// # Safety
	///
	/// The casting must be done to the correct struct.
	///
	/// You should always prefer the specific notifications, which perform this
	/// conversion for you.
	pub unsafe fn cast_nmhdr_mut<T>(&self) -> &mut T {
		#[allow(invalid_reference_casting)] // https://github.com/rust-lang/rust/issues/116410
		&mut *(self.nmhdr as *const _ as *mut _)
	}
}